package com.yincai.carefreewater.tool;

import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;

import com.yincai.carefreewater.callback.MyHttpCallback;
import com.yincai.carefreewater.callback.StringCallback;
import com.yincai.carefreewater.constant.URLConstant;
import com.yincai.carefreewater.entity.Param;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;


import org.json.JSONException;
import org.json.JSONObject;

import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

/**
 * Created by $zhangke on 2017/5/16.
 * 网络访问工具类
 *
 */

public class OkHttpTool {
        private static final String TAG = "tag";
        public static final int DEFAULT_MILLISECONDS = 6000;       //默认的超时时间
        public static int REFRESH_TIME = 100;                       //回调刷新时间（单位ms）
        private static OkHttpClient.Builder okHttpClientBuilder;           //ok请求的客户端
        private  OkHttpClient okHttpClient;

        private static final MediaType MEDIA_TYPE_PNG = MediaType.parse("image/png");
        public static final MediaType JSON
                = MediaType.parse("application/json; charset=utf-8");//ok请求的客户端
    private Handler handler;
    private Gson gson;
        private OkHttpTool() {
            okHttpClientBuilder = new OkHttpClient.Builder();
            okHttpClientBuilder.connectTimeout(DEFAULT_MILLISECONDS, TimeUnit.MILLISECONDS);
            okHttpClientBuilder.readTimeout(DEFAULT_MILLISECONDS, TimeUnit.MILLISECONDS);
            okHttpClientBuilder.writeTimeout(DEFAULT_MILLISECONDS, TimeUnit.MILLISECONDS);
            handler=new Handler(Looper.getMainLooper());
            gson = new GsonBuilder().serializeNulls().create();


        }
        public static OkHttpTool getInstance() {
            return new OkHttpTool();

        }
        public  OkHttpClient getOkHttpClient() {
            if (okHttpClient == null) okHttpClient = okHttpClientBuilder.build();


            return okHttpClient;
        }

    //okHttp网络操作的方法
    //写一个方法供给request 给okHttpclient使用
    private void doRequest(Request request, final MyHttpCallback callback){
        callback.onBeforeRequest(request);
        Log.i(TAG, "doRequest: "+getOkHttpClient());
        okHttpClient.newCall(request).enqueue(new Callback() {
            //这些okhttp的回调方法执行在子线程里面，返回的数据为了给主线程使用，
            // 必须想办法把数据供给主线程使用，所以引用了自定义的回调接口
            @Override
            public void onFailure(final Call call, final IOException e) {
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        callback.onFailure(call,e);
                    }
                });
            }
            @Override
            public void onResponse(Call call,final Response response) throws IOException {
                if(response.isSuccessful()){
                    //返回数据成功的话就解析json串
                    String json=response.body().string();
                    final Object o=gson.fromJson(json,callback.type);//将json解析成对应的bean
                    //handler 除了可以发送Message 也可以发送 runnable对象
                    //这个runnable对象的run方法就执行在 handler对应的线程中 当前的案例中 会执行在主线程中
                    handler.post(new Runnable() {
                        @Override
                        public void run() {
                            //将response返回给主线程
                            callback.onSuccess(response,o);
                        }
                    });
                }else{
                    handler.post(new Runnable() {
                        @Override
                        public void run() {
                            callback.onError(response,"服务器返回错误");
                        }
                    });
                }
            }
        });
    }
    //返回字符串
    private void doRequest1(Request request, final StringCallback callback){
        callback.onBeforeRequest(request);
        Log.i(TAG, "doRequest: "+getOkHttpClient());
        okHttpClient.newCall(request).enqueue(new Callback() {
            //这些okhttp的回调方法执行在子线程里面，返回的数据为了给主线程使用，
            // 必须想办法把数据供给主线程使用，所以引用了自定义的回调接口
            @Override
            public void onFailure(final Call call, final IOException e) {
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        callback.onFailure(call,e);
                    }
                });
            }
            @Override
            public void onResponse(Call call,final Response response) throws IOException {
                if(response.isSuccessful()){
                    //返回数据成功的话就解析json串
                    final String json=response.body().string();
                    //handler 除了可以发送Message 也可以发送 runnable对象
                    //这个runnable对象的run方法就执行在 handler对应的线程中 当前的案例中 会执行在主线程中
                    handler.post(new Runnable() {
                        @Override
                        public void run() {
                            //将response返回给主线程
                            try {
                                callback.onSuccess(response,json);
                            } catch (JSONException e) {
                                e.printStackTrace();
                            }
                        }
                    });
                }else{
                    handler.post(new Runnable() {
                        @Override
                        public void run() {
                            callback.onError(response,"服务器返回错误");
                        }
                    });
                }
            }
        });
    }
    //GET方式返回数据，通过回调返回主线程数据
    public void doGet(String url, MyHttpCallback callback){
        Log.i(TAG, "doGet: "+url);
        Request request= new Request.Builder().url(url).get().build();
        doRequest(request,callback);
    }
    //GET方式返回数据，通过回调返回主线程数据 字符串
    public void doGet(String url, StringCallback callback){
        Log.i(TAG, "doGet: "+url);
        Request request= new Request.Builder().url(url).get().build();
        doRequest1(request,callback);
    }



    //post方法. username  password
    public void doPost(String url, Map<String ,String> params, MyHttpCallback  callback){
        Log.i(TAG, "doPost: 请求");
        FormBody.Builder formBuilder=new FormBody.Builder();
        if(params!=null){
            for (Map.Entry<String,String> entry:params.entrySet()) {
                formBuilder.add(entry.getKey(),entry.getValue());
            }
        }
        RequestBody body=formBuilder.build();
        Request request=new Request.Builder().url(url).post(body).build();
        doRequest(request,callback);
    }
    //post方法. username  password
    public void doPost(String url, Map<String ,String> params, StringCallback  callback){
        Log.i(TAG, "doPost: 请求");
        FormBody.Builder formBuilder=new FormBody.Builder();
        if(params!=null){
            for (Map.Entry<String,String> entry:params.entrySet()) {
                formBuilder.add(entry.getKey(),entry.getValue());
            }
        }
        RequestBody body=formBuilder.build();
        Request request=new Request.Builder().url(url).post(body).build();
        doRequest1(request,callback);
    }

    /**
     * @param url
     * @param params
     * @return
     *
     * 拼接参数用于get请求
     */
    public String getPath(String url, Param[] params){
        String str="";
        for (Param param : params)
        {
            if(param.getValue()==null||param.getValue().length()==0){
                param.setValue("");
            }
            str+=param.getName()+"="+param.getValue()+"&";
        }
        str=str.substring(0,str.length()-1);
        String path= URLConstant.HOST+url+str;
        Log.i(TAG, "getPath: "+path);
        return path;

    }

    /**
     * @param url
     * @param params
     * @return
     * 拼接参数用于get请求
     */
    public String getPath(String url, Map<String,String> params){
        String str="";
        Set<Map.Entry<String, String>> entries = params.entrySet();
        Iterator<Map.Entry<String, String>> iterator = entries.iterator();
        while (iterator.hasNext()){

            Map.Entry<String, String> next = iterator.next();

            if(next.getValue()==null||next.getValue().length()==0){
                next.setValue("");
            }
            str+=next.getKey()+"="+next.getValue()+"&";

        }
        if (params.size()>0){

        str=str.substring(0,str.length()-1);
        }
        String path=URLConstant.HOST+url+str;
        Log.i(TAG, "getPath: "+path);
        return path;

    }



    /**
     * @param url
     *
     * post 请求
     */
    private Request buildPostRequest(String url, Param[] params) {
        if (params == null)
        {
            params = new Param[0];
        }
        FormBody.Builder builder = new FormBody.Builder();
        Log.i("tag", "buildPostRequest: "+params.length);

        for (Param param : params)
        {
            if(param.getValue()==null||param.getValue().length()==0){
                param.setValue("");            }
            builder.add(param.getName(), param.getValue());
        }
        RequestBody requestBody = builder.build();
        return new Request.Builder()
                .url(url)
                .post(requestBody)
                .build();
    }


    /**
     * @param json
     * @param msg
     * 用于加载数据正常之后提示
     *
     */
    public  boolean tostMsg(String json, String msg){
        try {
            JSONObject js=new JSONObject(json);
            String code = js.optString("code");
            if(code.equals("100")){
                ToastTool.toast(msg);
                return true;
            }else {
                String ms = js.optString("msg");
                ToastTool.toast(ms);
                return false;
            }

        } catch (JSONException e) {
            e.printStackTrace();
        }
        return false;
    }


    /**
     * @param path
     * @param hand
     * 上传 文件
     */
    public    void uploadFile(String path, final Handler hand) {
        // mImgUrls为存放图片的url集合
        MultipartBody.Builder builder = new MultipartBody.Builder().setType(MultipartBody.FORM);
        File f=new File(path);
        if (f!=null) {
            builder.addFormDataPart("upload_file", f.getName(), RequestBody.create(MEDIA_TYPE_PNG, f));
        }
        MultipartBody requestBody = builder.build();
        //构建请求
        Request request = new Request.Builder()
                .url(URLConstant.HOST+URLConstant.DEVICE_UPFILE)//地址
                .post(requestBody)//添加请求体
                .build();
        okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.i(TAG, "onResponse: +uploadImg"+e);
            }
            @Override
            public void onResponse(Call call, Response response) throws IOException {
                String str=response.body().string();
                Message msg=hand.obtainMessage(0,str);
                hand.sendMessage(msg);
            }
        });


    }

}

